package scut.facerecognition.WebSocket;

import com.alibaba.fastjson.JSON;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import scut.facerecognition.entity.pojo.Message;
import scut.facerecognition.service.MessageService;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * WebSocket服务
 */
@Slf4j
@Component
@ServerEndpoint("/chat/{userId}")
public class WebSocketServer {
    /**
     * 记录在线连接
     */
    public static final Map<Long, Session> sessionMap = new ConcurrentHashMap<>();

    /**
     * 注入messageService
     */
    private static MessageService messageService;
    @Autowired
    public void setMessageService(MessageService messageService) {
        WebSocketServer.messageService = messageService;
    }

    /**
     * 获取当前在线人数/
     * @return
     */
    private static synchronized int getOnlineCount() {
        return sessionMap.size();
    }

    /**
     * 与某个客户端的连接会话
     * @param session
     * @param userId
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") Long userId) {
        sessionMap.put(userId, session);
        log.info("用户 {} 连接，当前在线：{}", userId, sessionMap.size());

        // 用户上线后立即推送未读消息
        List<Message> unreadMessages = messageService.getUnreadMessages(userId);
        unreadMessages.forEach(msg -> {
            try {
                session.getBasicRemote().sendText(JSON.toJSONString(msg));
                messageService.updateDeliveryStatus(msg.getMessageId(), true); // 标记为已送达
            } catch (IOException e) {
                log.error("离线消息推送失败: {}", msg.getMessageId(), e);
            }
        });
    }

    /**
     * 收到客户端消息后调用的方法
     * @param message 收到的消息
     * @param senderId 发送者ID
     */
    @OnMessage
    public void onMessage(String message, @PathParam("userId") Long senderId) {
        // 数据处理,把接收到的json格式的message映射成一个java中的对象（Message）
        Message msg = JSON.parseObject(message, Message.class);
        msg.setSenderId(senderId);
        msg.setCreateTime(LocalDateTime.now());
        msg.setMessageStatus(true); // 标记为已成功保存到服务端

        // 保存消息到数据库
        messageService.save(msg);

        // 尝试实时推送
        Session receiverSession = sessionMap.get(msg.getReceiverId());
        if (receiverSession != null) {
            try {
                receiverSession.getBasicRemote().sendText(JSON.toJSONString(msg));
                msg.setIsDelivered(true);
                messageService.updateDeliveryStatus(msg.getMessageId(), true);
            } catch (IOException e) {
                log.error("实时消息投递失败: {}", msg.getMessageId(), e);
            }
        }
    }


    @OnClose
    public void onClose(@PathParam("userId") Long userId) {
        sessionMap.remove(userId);
        log.info("用户 {} 断开，剩余在线：{}", userId, sessionMap.size());
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.error("WebSocket 错误：", error);
    }

}